/*
*       A simple 2D game map editor
*
*       This library is free software; you can redistribute it and/or
*       modify it under the terms of the GNU Lesser General Public
*       License as published by the Free Software Foundation; either
*       version 2.1 of the License, or (at your option) any later version.
*/
// Name        : mapwidget
// File        : mapwidget.cpp
// Description :
// Author      : hoha
// Date        : 01/07/2009
// Evolutions  : 01/07/2009, Version V0, Creation
#include "widget_map.h"
#include "gm_map.h"
#include <QRect>
#include <QMouseEvent>
#include <QRgb>
#include <QPen>
#include <stdio.h>
#include <stdlib.h>

int locked_tile = 0;

void Wt_Map::init_border_grid()
{
	game_map_border_points_base.setX(0);
	game_map_border_points_base.setY(game_map_width*(TILE_HEIGHT/2));
	game_map_border_points_bl.setX(game_map_height*(TILE_WIDTH/2));
	game_map_border_points_bl.setY(map_height);
	game_map_border_points_tr.setX(game_map_width*(TILE_WIDTH/2));
	game_map_border_points_tr.setY(0);
	game_map_border_points_br.setX(map_width);
	game_map_border_points_br.setY(game_map_height*(TILE_HEIGHT/2));
	number_of_lines = (game_map_width+1) + (game_map_height + 1);
	//init map grid
	game_map_border = new QLine[number_of_lines];
	//init grid x cord
	for(u16 i=0; i< (game_map_height + 1); i++)
	{
		game_map_border[i].setLine(game_map_border_points_base.x() + i*(TILE_WIDTH/2), \
				game_map_border_points_base.y() + i*(TILE_HEIGHT/2),\
				game_map_border_points_tr.x() + i*(TILE_WIDTH/2),\
				game_map_border_points_tr.y() + i*(TILE_HEIGHT/2));
	}
	//init grid y cord
	for(u16 i =0; i< (game_map_width + 1); i++)
	{
		game_map_border[i+(game_map_height+1)].setLine(game_map_border_points_base.x() + i*(TILE_WIDTH/2),\
				game_map_border_points_base.y() - i*(TILE_HEIGHT/2),
				game_map_border_points_bl.x() +  i*(TILE_WIDTH/2),\
				game_map_border_points_bl.y() -  i*(TILE_HEIGHT/2));
	}
}

Wt_Map::Wt_Map(QWidget *parent)
: QWidget(parent)
{
	//***********************************************
	//init game map size
        game_map_width = 30;
        game_map_height = 30;
	//init map window size
	map_width = (game_map_width + game_map_height)*(TILE_WIDTH/2);
	map_height = (game_map_width + game_map_height)*(TILE_HEIGHT/2);
	this->setMinimumSize(map_width, map_height);
	//init map border and grid
	game_map_border = NULL;
	this->init_border_grid();
	//init map memory
	map = NULL;
	this->init_map();

	game_locked_tile_x =0; //.setX(0);
	game_locked_tile_y =0; //.setY(0);

	//***********************************************
}

Wt_Map::~Wt_Map()
{
	//free grid
	if(NULL!=game_map_border)
	{
		delete[] game_map_border;
		game_map_border = NULL;
	}
	//free map
	for(int i=0; i< game_map_width; i++)
	{
		delete[] map->map_core[i];
	}
        //delete[] map->map_core;
        //delete map_t;
}

void Wt_Map::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.setPen(QColor(255, 0, 0, 100));
	painter.setRenderHint(QPainter::Antialiasing, true);
	painter.drawLines(game_map_border, number_of_lines);

	for(int i=0; i<game_map_width; i++)
	{
		for(int j=0; j<game_map_height; j++)
		{
			if(TILE_U16_NS != map->map_core[i][j].tile_id)
			{
				int tileid = map->map_core[i][j].tile_id;
				painter.drawPixmap(map->map_core[i][j].screen_pos_x, map->map_core[i][j].screen_pos_y,\
						*memtileset->mem_entry[tileid].img_data_p,\
						0,0, memtileset->mem_entry[tileid].img_data_p->width(),\
						memtileset->mem_entry[tileid].img_data_p->height());
			}
		}
	}

	/*
	//painter.drawText(100,100,"what the fuck!");
	for(int i =0; i<20; i++)
	{

	for(int j =0; j<10; j++)
	{
	this->PosGameToScreen(game_map_border_points_base.x(),game_map_border_points_base.y(),\
	i, j, test_x, test_y);
	QString idx= QString::number(i);
	QString idy = QString::number(j);
	painter.drawText(test_x+20, test_y+20, idx);
	painter.drawText(test_x+20, test_y+30, idy);
	//painter.drawImage(test_x, test_y, *map_image, 0, 0, map_image->width(), map_image->height(), Qt::AutoColor);
	}
	}
	 */


}

void Wt_Map::mousePressEvent(QMouseEvent *event)
{
/*
	this->PosScreenToGame(game_map_border_points_base.x(),game_map_border_points_base.y(),\
			event->x(), event->y(), game_locked_tile_x, game_locked_tile_y);
        this->fill_cell_with_tile(game_locked_tile_x, game_locked_tile_y, locked_tile);
  */      this->fill_map_with_tile(locked_tile);
	update();

}

void Wt_Map::mouseMoveEvent(QMouseEvent *event)
{
	this->PosScreenToGame(game_map_border_points_base.x(),game_map_border_points_base.y(),\
			event->x(), event->y(), game_locked_tile_x, game_locked_tile_y);
	//if(true!=map->map_core[game_locked_tile_x][game_locked_tile_y].is_valid)
	//{
        this->fill_cell_with_tile(game_locked_tile_x, game_locked_tile_y, locked_tile);
	//}
	update();
}

void Wt_Map::keyPressEvent(QKeyEvent *k)
{
    if(k->key() == Qt::Key_Shift)
    {
      this->is_move_filling = true;
      printf("\n shift pressed\n");
    }
}

void Wt_Map::keyReleaseEvent(QKeyEvent *k)
{
    if(k->key() == Qt::Key_Shift)
    {
      this->is_move_filling = false;
      printf("\n shift released\n");
    }
}

bool Wt_Map::fill_cell_with_tile(int map_x, int map_y, int tile_id)
{
	if((map_x >=0)&&(map_x<game_map_width)&&(map_y>=0)&&(map_y<game_map_height))
	{
                map->map_core[map_x][map_y].tile_id = tile_id;
	}
}

bool Wt_Map::fill_map_with_tile(int tile_id)
{
    for( int x=0; x< game_map_width; x++)
    {
            for(int y =0; y< game_map_height; y++)
            {
                 map->map_core[x][y].tile_id = tile_id;
            }
    }
}

bool Wt_Map::init_map()
{
	map = new map_t;
	map->head.version=0;
	map->map_core = new map_core_t*[game_map_width];
	for(int i=0; i< game_map_width; i++)
	{
		map->map_core[i] = new map_core_t[game_map_height];
	}
	int x, y;
	for( x=0; x< game_map_width; x++)
	{
		for(y =0; y< game_map_height; y++)
		{
			this->PosGameToScreen(game_map_border_points_base.x(),game_map_border_points_base.y(),\
					x, y, (map->map_core[x][y].screen_pos_x), (map->map_core[x][y].screen_pos_y));
			map->map_core[x][y].tile_id = TILE_U16_NS;
		}
	}
	return true;
}

inline void Wt_Map::PosGameToScreen(int base_x, int base_y, int G_x, int G_y, int &S_x, int &S_y)
{
	S_x = (G_y + G_x) * (TILE_WIDTH>>1) + base_x;
	S_y = (G_y - G_x) * (TILE_HEIGHT>>1) -( TILE_HEIGHT>>1) + base_y;
}

inline void Wt_Map::PosScreenToGame(int base_x, int base_y, int S_x, int S_y, int &G_x, int &G_y )
{
	float fn, fm;
	fn = (S_x - base_x) / (TILE_WIDTH*1.0f) - (S_y - base_y) / (TILE_HEIGHT*1.0f);
	fm = (S_x - base_x) / (TILE_WIDTH*1.0f) + (S_y - base_y) / (TILE_HEIGHT*1.0f);

	if (fn < 0)
	{
		G_x = (int)fn - 1;
	}
	else
	{
		G_x = (int)fn;
	}

	if (fm < 0)
	{
		G_y = (int)fm - 1;
	}
	else
	{
		G_y = (int)fm;
	}
}

